home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / opengl / motif / otessellate.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  10.0 KB  |  410 lines

  1. /*
  2.  * Copyright 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*----------------------------------------------------------------------------
  18.  *
  19.  * otessellate.c : openGL (motif) example showing how to tessellate
  20.  *                 concave polygons and polygons with holes
  21.  *
  22.  * Author : Yusuf Attarwala
  23.  *          SGI - Applications
  24.  * Date   : Sep 93
  25.  *
  26.  *    press  left   button for animation
  27.  *    press  middle button to turn OFF tessellation
  28.  *    press  right  button to turn ON  tessellation
  29.  *
  30.  *---------------------------------------------------------------------------*/
  31. #include <stdio.h>
  32. #include <stdlib.h>
  33. #include <string.h>
  34.  
  35. #include <Xm/Xm.h> 
  36. #include <Xm/Frame.h>               /* for frame widgets */
  37. #include <Xm/Form.h>                /* for form  widgets */
  38. #include <X11/keysym.h>             /* keyboard translations */
  39. #include <X11/StringDefs.h>
  40.  
  41. #include <GL/gl.h>                  /* gl includes */
  42. #include <GL/glu.h>                 /* utility library includes */
  43. #include <GL/GLwMDrawA.h>           /* include for the drawing area widget */
  44.  
  45. static int tessellationOn = 0;
  46.  
  47. /* function declarations */
  48.  
  49. void 
  50.     createToplevel(void),
  51.     drawScene(void),
  52.     setMatrix(void),
  53.     animation(void),
  54.     doTessellation(void),
  55.     exposeCB(Widget,XtPointer,XtPointer),
  56.     resizeCB(Widget,XtPointer,XtPointer),
  57.     initCB(Widget,XtPointer,XtPointer),
  58.     inputCB(Widget,XtPointer,XtPointer);
  59.  
  60. /* callback functions for tessellator */
  61. void
  62.     myBegin(GLenum),
  63.     myVertex(void *),
  64.     myEnd(void),
  65.     myError(GLenum);
  66.  
  67. /* global variables */
  68.             
  69. Display       *display;       /* current display */
  70. XtAppContext  appContext;     /* X application context */
  71. float         ax,ay,az;       /* angles for animation */
  72.  
  73. Widget        toplevel,       /* toplevel shell */
  74.               glw;            /* current widget */
  75.              
  76. GLXContext    glxc;           /* current glx context */
  77.  
  78. Arg args[20];
  79. int acnt;
  80.  
  81. /* coords of outer star  */
  82.  
  83. static GLfloat outerColor[3] = {1.0,1.0,0.0};
  84.  
  85. static int nouter = 10;
  86. static GLfloat   outer[10][3] = {3.5,5.0,0.0,
  87.                                  2.0,2.0,0.0,
  88.                                  5.0,4.0,0.0,
  89.                                  8.0,2.0,0.0,
  90.                                  6.5,5.0,0.0,
  91.                                  8.0,6.0,0.0,
  92.                                  6.0,6.0,0.0,
  93.                                  5.0,8.0,0.0,
  94.                                  4.0,6.0,0.0,
  95.                                  2.0,6.0,0.0};
  96.  
  97. /* coords of inner star  */
  98.  
  99. static int ninner = 10;
  100. static GLfloat inner[10][3] = {3.8,5.0,0.0,
  101.                    2.6,2.6,0.0,
  102.                    5.0,4.2,0.0,
  103.                    7.4,2.6,0.0,
  104.                    6.2,5.0,0.0,
  105.                    7.4,5.8,0.0,
  106.                    5.8,5.8,0.0,
  107.                    5.0,7.4,0.0,
  108.                    4.2,5.8,0.0,
  109.                    2.6,5.8,0.0};
  110.  
  111.  
  112. /* display list identifier */
  113. GLuint tList = 1;
  114.  
  115. void 
  116. main(int argc, char** argv)
  117. {
  118.     XtToolkitInitialize();
  119.     appContext = XtCreateApplicationContext();
  120.     display    = XtOpenDisplay(appContext, NULL, "Otessellate","otessellate",NULL,0,
  121.                               &argc,argv);
  122.     if (!display) {
  123.         printf("%s : Unable to open display\n",argv[0]);
  124.         exit(0);
  125.     }
  126.  
  127.     printf("\n---------------------------------------------\n");
  128.     printf("OpenGL tessellation example \n\n");
  129.     printf("Press:  left   button for animation\n\
  130.         middle button to turn OFF tessellation (default)\n\
  131.         right  button to turn ON  tessellation \n");
  132.  
  133.     createToplevel();             /* create widget hierarchy */
  134.     XtAppMainLoop(appContext);    /* loop forever */
  135. }
  136.  
  137.  
  138. void
  139. createToplevel(void)
  140. {
  141.     Widget frame;
  142.  
  143.     acnt = 0;
  144.     XtSetArg(args[acnt],XmNminHeight, 300);acnt++;
  145.     XtSetArg(args[acnt],XmNminWidth,  300);acnt++;
  146.     XtSetArg(args[acnt],XmNminAspectX,  1);acnt++;
  147.     XtSetArg(args[acnt],XmNminAspectY,  1);acnt++;
  148.     XtSetArg(args[acnt],XmNmaxAspectX,  1);acnt++;
  149.     XtSetArg(args[acnt],XmNmaxAspectY,  1);acnt++;
  150.     toplevel  = XtAppCreateShell("openGL tessellate","otessellate",
  151.                                   applicationShellWidgetClass,
  152.                                   display,args,acnt);
  153.  
  154.     /* create a frame to hold glx widget */
  155.     frame   = XtVaCreateManagedWidget("frame", 
  156.                   xmFrameWidgetClass, toplevel, 
  157.                   NULL);
  158.  
  159.     /* create a double buffer widget, in rgb mode and manage it */
  160.     acnt = 0;
  161.     XtSetArg(args[acnt], GLwNrgba,               TRUE); acnt++;
  162.     XtSetArg(args[acnt], GLwNdoublebuffer,       TRUE); acnt++;
  163.     XtSetArg(args[acnt], GLwNallocateBackground, TRUE); acnt++;
  164.     glw = GLwCreateMDrawingArea(frame, "glw", args, acnt);
  165.     XtManageChild(glw);
  166.  
  167.     /* register callbacks */
  168.     XtAddCallback(glw, GLwNginitCallback,  initCB,   NULL);
  169.  
  170.     /* realize widget hierarchy */
  171.     XtRealizeWidget(toplevel);
  172.  
  173.     /* additional callbacks */
  174.     XtAddCallback(glw, GLwNexposeCallback, exposeCB, NULL);
  175.     XtAddCallback(glw, GLwNresizeCallback, resizeCB, NULL);
  176.     XtAddCallback(glw, GLwNinputCallback,  inputCB,  NULL);
  177.  
  178. }
  179.  
  180. void
  181. drawScene(void)
  182. {
  183.  
  184.     int i;
  185.  
  186.     glClearColor(0.0, 0.0, 0.0, 0.0);
  187.     glClear(GL_COLOR_BUFFER_BIT);
  188.  
  189.     glPushMatrix();
  190.  
  191.     glTranslatef(4.0,4.0,0.0);
  192.     glRotatef (ax,1.0,0.0,0.0);
  193.     glRotatef (-ay,0.0, 1.0, 0.0);
  194.     glRotatef (az,0.0, 0.0, 1.0);
  195.     glTranslatef(-4.0,-4.0,0.0);
  196.  
  197.     /* all the good stuff follows */
  198.  
  199.     if (tessellationOn) {
  200.     /* draw the tessellated polygons (stored in display list) */
  201.     glCallList(tList);
  202.     }
  203.     else {
  204.     /* draw the original polygons */
  205.     glColor3fv(outerColor);
  206.     glBegin(GL_LINE_LOOP);
  207.         for (i=0;i<nouter;i++) {
  208.         glVertex3fv((GLfloat *)outer[i]);
  209.         }
  210.     glEnd();
  211.  
  212.     glBegin(GL_LINE_LOOP);
  213.         for (i=0;i<ninner;i++) {
  214.         glVertex3fv((GLfloat *)inner[i]);
  215.         }
  216.     glEnd();
  217.     }
  218.  
  219.     /* end of good stuff */
  220.     glPopMatrix();
  221.  
  222.     glFlush();
  223.     glXSwapBuffers(XtDisplay(glw), XtWindow(glw));
  224.  
  225. }
  226.  
  227. void
  228. setMatrix(void)
  229. {
  230.     glMatrixMode(GL_PROJECTION);
  231.     glLoadIdentity();
  232.     glOrtho(-0.5,9.5,-0.5,9.5,-10.0,10.0);
  233.     glMatrixMode(GL_MODELVIEW);
  234.     glLoadIdentity();
  235. }
  236.  
  237. void
  238. animation(void)
  239. {
  240.     register int i;
  241.     /* animate the star */
  242.  
  243.     for (i=0;i<60;i++) {
  244.     /*
  245.         ax += 1.5;
  246.         ay -= 2.5;
  247.     */
  248.         az += 3.0;
  249.         if (ax >= 360)  ax = 0.0;
  250.         if (ay <= -360) ay = 0.0;
  251.         if (az >= 360)  az = 0.0;
  252.         drawScene();
  253.     }
  254. }
  255.  
  256. void 
  257. inputCB(Widget w, XtPointer client_data, XtPointer call)
  258. {
  259.     static int firstTime = 1;
  260.     char            string[31];
  261.     XComposeStatus  composeStatus;
  262.     KeySym keysym;
  263.     GLwDrawingAreaCallbackStruct *call_data;
  264.  
  265.     call_data = (GLwDrawingAreaCallbackStruct *) call;
  266.  
  267.     switch(call_data->event->type) {
  268.     case ButtonPress:
  269.         switch (call_data->event->xbutton.button) {
  270.         case Button1:
  271.         animation();
  272.             break;
  273.         case Button2 :
  274.         tessellationOn = 0;
  275.         XtVaSetValues(toplevel,XmNtitle, "No Tessellation",NULL);
  276.         drawScene();
  277.             break;
  278.         case Button3 :
  279.         tessellationOn = 1;
  280.         if (firstTime) {
  281.         firstTime = 0;
  282.         doTessellation();
  283.         }
  284.         XtVaSetValues(toplevel,XmNtitle, "Tessellated Polygons",NULL);
  285.         drawScene();
  286.             break;
  287.         }
  288.         break;
  289.     case KeyPress :
  290.         XLookupString((XKeyEvent *)call_data->event,string,
  291.                       30,&keysym,&composeStatus);
  292.         switch(keysym) {
  293.         case XK_Escape :
  294.             exit(0);
  295.             break;
  296.         }
  297.     break;
  298.     default:
  299.         break;
  300.     }
  301. }
  302.  
  303. void 
  304. resizeCB(Widget w, XtPointer client_data, XtPointer call)
  305. {
  306.     GLwDrawingAreaCallbackStruct *call_data;
  307.     call_data = (GLwDrawingAreaCallbackStruct *) call;
  308.  
  309.     GLwDrawingAreaMakeCurrent(w, glxc);
  310.     glViewport(0, 0, call_data->width, call_data->height);
  311.     setMatrix();
  312.  
  313.     drawScene();
  314. }
  315.  
  316. void 
  317. exposeCB(Widget w, XtPointer client_data, XtPointer call)
  318. {
  319.     GLwDrawingAreaCallbackStruct *call_data;
  320.     call_data = (GLwDrawingAreaCallbackStruct *) call;
  321.  
  322.  
  323.     GLwDrawingAreaMakeCurrent(w, glxc);
  324.     glViewport(0, 0, call_data->width, call_data->height);
  325.     drawScene();
  326. }
  327.  
  328. void
  329. initCB(Widget w, XtPointer client_data, XtPointer call)
  330. {
  331.     XVisualInfo *vi;
  332.  
  333.     XtSetArg(args[0], GLwNvisualInfo, &vi);
  334.     XtGetValues(w, args, 1);
  335.  
  336.     glxc = glXCreateContext(XtDisplay(w), vi, 0, GL_TRUE);
  337.  
  338.     ax = 10.0;
  339.     ay = -10.0;
  340.     az = 0.0;
  341. }
  342.  
  343. void
  344. doTessellation()
  345. {
  346.     int i;
  347.     GLUtriangulatorObj *tobj;
  348.     GLdouble db3[3];
  349.  
  350.     /* create a tessellation object */
  351.     tobj = gluNewTess();
  352.  
  353.     /* register callbacks */
  354.     gluTessCallback(tobj,GLU_BEGIN, myBegin);
  355.     gluTessCallback(tobj,GLU_VERTEX,myVertex);
  356.     gluTessCallback(tobj,GLU_END,   myEnd);
  357.     gluTessCallback(tobj,GLU_ERROR, myError);
  358.  
  359.     glNewList(tList,GL_COMPILE);
  360.     glColor3fv(outerColor);
  361.  
  362.     gluBeginPolygon(tobj);
  363.     for (i=0;i<nouter;i++) {
  364.     db3[0] = (GLdouble) outer[i][0];
  365.     db3[1] = (GLdouble) outer[i][1];
  366.     db3[2] = (GLdouble) outer[i][2];
  367.     gluTessVertex(tobj,(GLdouble *)db3,(void *)outer[i]);
  368.     }
  369.     gluNextContour(tobj,GLU_INTERIOR);
  370.     for (i=0;i<ninner;i++) {
  371.     db3[0] = (GLdouble) inner[i][0];
  372.     db3[1] = (GLdouble) inner[i][1];
  373.     db3[2] = (GLdouble) inner[i][2];
  374.     gluTessVertex(tobj,(GLdouble *)db3,(void *)inner[i]);
  375.     }
  376.     gluEndPolygon(tobj);
  377.  
  378.     glEndList();
  379.  
  380.     /* free the tess obj, when done */
  381.     gluDeleteTess(tobj);
  382. }
  383.  
  384. void
  385. myBegin(type)
  386. GLenum type;
  387. {
  388.     glBegin(type);
  389. }
  390.  
  391. void
  392. myVertex(data)
  393. void *data;
  394. {
  395.     glVertex3fv((GLfloat *)data);
  396. }
  397.  
  398. void
  399. myEnd()
  400. {
  401.     glEnd();
  402. }
  403.  
  404. void
  405. myError(errnum)
  406. GLenum errnum;
  407. {
  408.     printf("myError %s \n",gluErrorString(errnum));
  409. }
  410.